home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48hor2 / bnf.doc < prev    next >
Text File  |  1995-03-31  |  15KB  |  340 lines

  1. This is the summary of chapter 11 'RPL READER and Parser Tools' from the HP 
  2. Kernel ERS, August 7, 1986; it's a transcription with minor modifications 
  3. where neccassary. Thanks to HP Cv. for giving the permission to publish BNF. 
  4.  
  5. ----------------------------------------------------------------------------- 
  6.  
  7. 11.3 Parser Tools and the BNF parser 
  8.  
  9. The parser tools are modelled after the PRISM system MINI utility which is a 
  10. parser generator (pg) program. The definition of a parser, for our purposes, 
  11. is a function which takes arguments in the form 
  12.   ob1 .. obn n toktyptab string offset token 
  13. and returns results in the form 
  14.   ob1' .. obn' n' toktypetab' string offset' token' flag TRUE 
  15. or 
  16.   ob1 .. obn n toktyptab string offset token FALSE 
  17.  
  18. The interpretation of these pieces conforms to the intuitive notion of a 
  19. parser. ob1 .. obn are objects previously parsed, and n is a binary int 
  20. representing the number of objects. Toktypetab is a token-type table (see 
  21. below). String is the string being parsed, token is also a string, but 
  22. represents the piece of the string currently being considered. Offset is a 
  23. binary int offset into (or beyond) the string and points to the 1st char 
  24. not accounted for in the token. 
  25.  
  26. The flags returned have the following interpretation. If FALSE is returned, 
  27. then parsing was never started. If TRUE TRUE is returned, then parsing was 
  28. started and successfully completed. If FALSE TRUE is returned, then parsing 
  29. was started, but not completed (usally an error condition). 
  30.  
  31. The pg 'BNF' (see below) produces a parser from its Backus-Naur-Form 
  32. description given as a string. The BNF consists of a sequence of clauses 
  33. seperated by '/'s. Each clause is a sequence of parsers. The evaluation of a 
  34. BNF of the form A B C ... 1st evaluates A, and if A returns FALSE, then B C 
  35. ... is ignored and FALSE is returned. If A returns FALSE TRUE, then B C ... 
  36. is again ignored and FALSE TRUE is returned. If A returns TRUE TRUE then B C 
  37. ... is evaluated sequentially until either a FALSE or a FALSE TRUE is 
  38. returned, or the sequence completes. In the 1st case FALSE TRUE is returned, 
  39. in the 2nd case TRUE TRUE is returned. 
  40.  
  41. A BNF of the form A B / C D is evaluated by evaluating A B as above, and if 
  42. the result is FALSE, then evaluate C D as above and return whatever is 
  43. returned by this evaluation. On the other hand, if the evaluation of A B 
  44. returns TRUE TRUE or FALSE TRUE, then C D is not evaluated, and the result 
  45. of A B is returned. 
  46.  
  47. As an example, consider the parser for a list of names: 
  48.   list: 
  49.      leftparen terminator 
  50.   terminator: 
  51.      rightparen / name terminator / list terminator 
  52.  
  53. From this description, you can see that (), ( ABC ), ( ABC ( CDE ) ), etc. 
  54. are all lists. 
  55.  
  56. The pg is invoked by the word 'BNF' and expect a string in level 1 which 
  57. contains the BNF description of a parser. The string starts with the token 
  58. "BNF" and is ended by the token "ENDBNF". Between these two, and in addition 
  59. to the clause seperator "/", the following are allowed: 
  60.   - an name of a variable in the current directory, assumed to be a parser. 
  61.   - the token " followed by another token. 
  62.   - the token CK" followed by another token. 
  63.   - the token // used in the same way as / 
  64.  
  65. The parser corresponding to " creates a parser using the token that follows. 
  66. The parser created doesn't start unless the current token corresponds to that 
  67. parser to the creator. If a match is made, then the created parser returns 
  68. TRUE TRUE and drops the current token and gets the next one. 
  69.  
  70. The parser corresponding to CK" is nearly identical to the above, exept that 
  71. it leaves the current token right where it is. 
  72.  
  73. The // is used as a clause seperator with the same meaning as /, except that 
  74. it modifies the manner in which the last object in the terminated clause is 
  75. evaluated. It's usefull for tail-recursive calls to a parser which allways 
  76. completes or fails, that is never returns FALSE. If such a parser is the last 
  77. object in a clause, then it can be evaluated with a COLA. The token // 
  78. indicates such a situation to the BNF parser. 
  79.  
  80. 11.4 Extensible Parsers 
  81.  
  82.   [Some text I didn't understand about !*XTNDPA and LAM !*FAILTOKENS, a 
  83.    extensible parser sheme, build-in into the RPL development system...] 
  84.  
  85. ... I suggest that a bottom-level RAM- or ROM-WORD which designates a parser 
  86. should be named !*<name>PA [I've strip the dammed !*]. 
  87.  
  88. To further refine the conventions for parser, we need to pick out two 
  89. fundamental kinds of parsers. Although many parsers will not fall strictly 
  90. in one category or the other, most, if not all, parsers can be decomposed, 
  91. BNF-style, into parsers of these two fundamental kinds. The two kinds of 
  92. parsers may be called production parsers and reduction parsers. They are 
  93. distinguished by their action on tokens and currently parsed objects. 
  94.  
  95. A production parser ignores already parsed objects and only operates on the 
  96. string and token to produce a sequence of objects. In stack notation: 
  97.  
  98.   ob1 .. obn n toktyptab string offset token --> 
  99.   ob1 .. obn n ob1' .. obn' n' toktypetab' string offset' token' flag TRUE 
  100. or 
  101.   ob1 .. obn n toktyptab string offset token FALSE 
  102.  
  103. In particular, a production parser returns a single sequence of objects and 
  104. the number of objects, if it successfully completes parsing, and leaves the 
  105. objects already on the stack unchanged. 
  106.  
  107. In contrast, a reduction parser doesn't alter the current offset or token and 
  108. instead takes the sequence or sequences of objects on the stack and rearranges 
  109. and/or combines them into new objects or sequences. Most reduction parsers 
  110. will take a fixed number of sequences of objects, with restrictions on the 
  111. number of objects in each sequence and return a new sequence. In stack 
  112. notation: 
  113.   <seq 1> n1 .. <seq n> nn toktypetab string offset token --> 
  114.   <seq 1>' n1' .. <seq n>' nn' toktypetab string offset token flag TRUE 
  115.  
  116. A further convention on parser will be that any parser should be, in its net 
  117. effect, a production parser. That is to say that even though a parser may be 
  118. composed of sub-parsers which may be either production or reduction parser, 
  119. the net effect of the parser, when successfully completed, should be that of 
  120. a production parser. 
  121.  
  122. 11.4.1 An Example 
  123.  
  124. As an example of the use of the BNF pg, the generator is given in terms of 
  125. itself (and a few other pieces). In the example, named subparsers which are 
  126. production parsers will begin with a capital letter. 
  127.  
  128.   [I used this example to create the *WORKING* (I wonder, if HP have ever 
  129.    check the functionality of their examples ;-) BNF pg in the directory 
  130.    BNFPG. I also bring the example to work, you can find it in the 
  131.    subdirectory BNFXMPL (to run it, 1st run the BNFPG-SETUP and install the 
  132.    resulting library).] 
  133.  
  134. The parser BNFPA produces a parser function from a clause or sequence of 
  135. clauses seperated by '/'s or '//'s. Its operation is quite simple, but has 
  136. several features which recognize special situations to aid the effeciency of 
  137. the resulting function [ROTFLL :-]. 
  138.  
  139. In the general case, a clause of the form A B .. C / is transformed into 
  140.   ID A !*trior :: ID B !*triand .. ID C !*triand TrueTrue ; 
  141.  
  142. and a clause of the form A B .. C // is transformed into 
  143.   ID A !*trior :: ID B !*triand .. COLA ID C ; 
  144.  
  145. A sequence of clauses is tramsformed into the concatenation of the forms 
  146. shown above and, when the ENDBNF is encoutered, a FALSE is appended to the 
  147. form and the entire form is collected into a secondary which is then the 
  148. parser function. 
  149.  
  150.   [you will find an explaination for !*trior and !*triand along with some 
  151.    other entries below.] 
  152.  
  153. The two special cases arise when there's only one object in a clause. 
  154.  
  155. Normally, a clause of the form A / would produce 
  156.   ID A !*trior :: TrueTrue ; 
  157.  
  158. This can be replaced by 
  159.   ID A !*trior TrueTrue 
  160.  
  161. The 2nd case arises when the single-object clause is the final clause in the 
  162. BNF description. Something of the form 
  163.   BNF ... A ENDBNF 
  164.  
  165. would produce 
  166.   :: ... A !*trior TrueTrue FALSE ; 
  167.  
  168. Since A is (assumed to be) a parser, when it's evaluated it will return the 
  169. tristate-flag on top of the stack. The net result is exactly the same as if 
  170. A alone were evaluated. For this reason, BNF will produce 
  171.   :: ... COLA A ; 
  172.  
  173.   [As an specific example of the output of the BNF parser, run the BNFPXMPL- 
  174.    SETUP, store the resulting directory and then decompile e.g. Bnfob using 
  175.    RPL->.] 
  176.  
  177. 11.5 Tokens and Token-Type Tables 
  178.  
  179.   [They are telling us what a token is - see the description of the built-in 
  180.    GetNextToken below] 
  181.  
  182. 11.6 BNF Description of the READER 
  183.  
  184.   [Description of a program in their RPL development system, similar to ->RPL. 
  185.    Long and unusefull.] 
  186.  
  187. 11.7 Provided Objects 
  188.  
  189. GetNextToken 
  190. ( hxs $ # --> hxs $ #' $' ) 
  191.   where hxs is a token-type table, $ is a string and # is an offset (in 
  192.   chars) into the string. Returns the ttt, the string, the offset to the 
  193.   first char not used in the token, and the token. 
  194.  
  195.   The ttt is a a hxs containing 256 elements, one for each char. The table 
  196.   gives an implicit correspondence between ASCII characters and their TYPE, 
  197.   which is one of 16 values: 
  198.         0  - neutral character 
  199.         1  - normal character 
  200.         2  - digit 
  201.         3  - left delimiter 
  202.         4  - right delimiter 
  203.         5  - self delimiter 
  204.         6  - escape character 
  205.         7  - diphthong start 
  206.  
  207.         [Not described in the ERS, but built-in in the HP48 GetNextToken: ] 
  208.  
  209.         8  - ? 
  210.         9  - ? 
  211.         10 - ? 
  212.         11 - ? 
  213.         12 - ? 
  214.         13 - comment toggle 
  215.         14 - comment off 
  216.         15 - ? 
  217.  
  218.   GetNextToken scans the string beginning at the offset until it finds the 
  219.   1st non-neutral character (or the end of the string). If this char is a 
  220.   left-delimiter, a right-delimiter or a self-delimiter, then this char is 
  221.   returned as the token and the new offset points just beyond it. 
  222.  
  223.   If the 1st non-neutral char is a dipthong-start, then this char and the 
  224.   following char are returned as the token. 
  225.  
  226.   If none of the above have occured, then the type of the token is determined 
  227.   from the type of the 1st char, with the exception that a char of type 6 
  228.   forces itself and the char following it to be interpreted as type 1. Then 
  229.   chars from the string are accumulated into the token until a type change 
  230.   occurs, or the offset gos beyond the end of the string. The accumulated 
  231.   token (with chars of a uniform type) is returned and the offset returned 
  232.   points beyond the last char which was added to the token. 
  233.  
  234.   Note that since one of the arguments for a parser is a token, each parser 
  235.   that successsfully completes parsing must provide the token for the next 
  236.   parser in line for evaluation. In particular, the ttt for entry into a 
  237.   given parser is determined by the previous successfully completed parser. 
  238.  
  239.   [Comments: 
  240.    Digits are treated as ordinary chars if they follow an ordinary char. 
  241.    Chars between two comment toggles behave as neutral chars.] 
  242.  
  243. !*Tok [PTR BC15] 
  244. ( hxs $ # $' $'' --> hxs $ # $' FALSE ) 
  245. ( hxs $ # $' $'' --> hxs $''' #' $'''' TRUE TRUE ) 
  246.   If the string on the top of the stack matches the string just beneath it, 
  247.   the top two strings are dropped, GetNextToken is evaluated and TRUE TRUE is 
  248.   subsequently returnde. Otherwise, the top string is dropped and FALSE is 
  249.   returned. 
  250.  
  251. !*tokck [PTR BC47] 
  252. ( hxs $ # $' $'' --> hxs $ # $' FALSE ) 
  253. ( hxs $ # $' $'' --> hxs $ # $' TRUE TRUE ) 
  254.   If the top two strings match, the top string is dropped and TRUE TRUE is 
  255.   returned, otherwise the top string is dropped and FALSE is returned. 
  256.  
  257. !*trior 
  258. ( FALSE --> ? ) 
  259. ( FALSE TRUE --> FALSE TRUE ) 
  260. ( TRUE TRUE --> ? ) 
  261.   In the 1st case, FALSE and the 1st object in the top body of the runstream 
  262.   are dropped, and execution resumes at the (former) second object. In the 
  263.   2nd case, the entire top body in the runstream is dropped. In the 3rd case, 
  264.   TRUE TRUE and the top body in the runstream are dropped, and the (former) 
  265.   1st object in the runstream is evaluated. 
  266.  
  267. !*triand 
  268. ( FALSE --> FALSE TRUE ) 
  269. ( FALSE TRUE --> FALSE TRUE ) 
  270. ( TRUE TRUE --> ? ) 
  271.   In the 1st case, TRUE is pushed on the stack; in either the 1st or the 2nd 
  272.   case, the top body in the runstream is dropped. In the 3rd case, the flags 
  273.   are dropped, and evaluation continues normally. 
  274.  
  275. TrueTrue 
  276. ( --> TRUE TRUE ) 
  277.  
  278. failed 
  279. ( --> FALSE TRUE ) 
  280.  
  281. ----------------------------------------------------------------------------- 
  282.  
  283. The BNF parser generator: 
  284.  
  285. In the BNF.DIR directory you'll find the following variables: 
  286.  
  287.   BNFXMPL       - BNF example: the BNF pg in terms of itself 
  288.   SETUP         - Run run this to create a BNF pg library (id 800) in stack 
  289.                   level 1. The <-RPL-> and <-LIB-> libraries must be 
  290.                   installed for it to work. 
  291.  
  292.   All following variables are source strings for ->RPL: 
  293.  
  294.   BED           - 'BNF EDitor', nice name .. ;-) 
  295.   BNF           - BNF pg user interface, feed this program with a BNF def. 
  296.   BNFPA         - BNF pg; named !*BNFPA in the ERS 
  297.   Bnfterm       - term parser 
  298.   Bnfcls        - clause parser 
  299.   Bnfob         - object parser 
  300.   Maketoken     - " pg 
  301.   Makeck        - CK" pg 
  302.   CompileID     - object pg 
  303.   fincls        - normal clause end 
  304.   colacls       - COLA clause end 
  305.   inscola       - append COLA to meta object 
  306.   &ob           - append two meta objects 
  307.   &nostart      - append 'failed' to meta object 
  308.   bnfsav        - save BNF pg context 
  309.   bnfrst        - restore BNF pg context 
  310.   TTT           - token-type table 
  311.  
  312. In the BNFXMPL directory you'll find the following variables (source strings, 
  313. ready for compiling/BNF pg'ing) : 
  314.  
  315.   SETUP         - Run it to genarate a directory in stack level 1. The 
  316.                   <-RPL->, <-LIB-> and BNF libraries must be installed for 
  317.                   it to work. 
  318.   bnf           - Same as BNF above. Change name to lower case, because of 
  319.                   the conflict with the lib-word BNF in the BNF lib. 
  320.   BNFPA         - BNF pg in BNF notation 
  321.   Bnfterm       - term parser in BNF notation 
  322.   Bnfcls        - clause parser in BNF notation 
  323.   Bnfob         - object parser in BNF notation 
  324.   Maketoken     - " pg 
  325.   Makeck        - CK" pg 
  326.   CompileID     - object pg 
  327.   startbnf      - start BNF pg 
  328.   finbnf        - close BNF pg 
  329.   startcls      - start clause 
  330.   fincls        - normal clause end 
  331.   colacls       - COLA clause end 
  332.   contcls       - next clause 
  333.   inscola       - append COLA to meta object 
  334.   &ob           - append two meta objects 
  335.   &nostart      - append 'ID failed' to meta object 
  336.   bnfsav        - save BNF pg context 
  337.   bnfrst        - restore BNF pg context 
  338.   failed        - FALSE TRUE 
  339.   TTT           - Token-type table 
  340.